/*
 * @Author: huirui@huanqiu.com
 * @Date: 2024-09-27 16:46:34
 * @LastEditors: huirui@huanqiu.com
 * @LastEditTime: 2024-10-08 20:32:19
 * @Description: 人民号
 */
// const puppeteer = require("puppeteer-extra");
// const stealth = require("puppeteer-extra-plugin-stealth")();
// stealth.enabledEvasions.delete("iframe.contentWindow");
// puppeteer.use(stealth);
const puppeteer = require("puppeteer");
const logger = require("../../utils/logger");
const userDataDir = process.env.WEB_CONFIG_USER_DATA_DIR;
const executablePath = process.env.WEB_CONFIG_EXECUTABLE_PATH;
const notification = require("../../utils/notification");
const { sendWechatMessage } = require("../../utils");
const md5 = require("md5");
const axios = require("axios");
const dayjs = require("dayjs");

//https://pdcreator.pdnews.cn/producer/analysis/content/single
// 准备流程
async function handlePrepare(page) {
  const dimensions = await page.evaluate(() => ({
    width: window.innerWidth,
    height: window.innerHeight,
  }));
  await page.setViewport(dimensions);
  await page.goto(
    "https://pdcreator.pdnews.cn/producer/analysis/content/single",
    {
      waitUntil: "networkidle2",
    }
  );
  // 检查当前URL是否包含登录页面
  const currentUrl = page.url();
  if (currentUrl.includes("https://pdcreator.pdnews.cn/login")) {
    logger.info("未登录，开始登录流程...");
    try {
      await login(page);
      logger.info("登录成功");
      // 等待页面导航完成
      await page.waitForNavigation({ waitUntil: "networkidle0" });
    } catch (error) {
      logger.error(`登录失败: ${error.message}`);
      throw error;
    }
  } else {
    logger.info("已登录");
  }
}

// 获取作品信息
async function getArticlesInfo(params) {
  let browser, page;
  try {
    browser = await puppeteer.launch({
      headless: false,
      userDataDir,
      executablePath,
      defaultViewport: null,
      args: [
        "--no-sandbox",
        "--disable-setuid-sandbox",
        "--disable-features=site-per-process",
        "--start-maximized",
      ],
      ignoreHTTPSErrors: true,
    });
    page = await browser.newPage();
    await handlePrepare(page);

    let results = [];
    let requestParams = null;
    let cookies = null;
    let headers = null;

    // 设置请求拦截
    await page.setRequestInterception(true);

    // 拦截请求并获取参数
    page.on("request", async (request) => {
      if (
        request
          .url()
          .includes(
            "https://pdcreator.pdnews.cn/api/rmrb-bigdata-bi/zh/b/creator/statistic/content/single/list"
          )
      ) {
        requestParams = JSON.parse(request.postData());
        cookies = await page.cookies();
        headers = request.headers();
        request.continue();
      } else {
        request.continue();
      }
    });

    // 触发初始请求
    await page.goto(
      "https://pdcreator.pdnews.cn/producer/analysis/content/single",
      { waitUntil: "networkidle2", timeout: 60000 }
    );

    // 等待获取到请求参数
    await new Promise((resolve) => setTimeout(resolve, 5000));

    if (!requestParams || !headers) {
      throw new Error("未能获取到请求参数或头信息");
    }

    // 构造 cookie 字符串
    const cookieString = cookies
      .map((cookie) => `${cookie.name}=${cookie.value}`)
      .join("; ");

    // 定义一个函数来获取特定类型的内容
    async function getContent(contentType) {
      let currentPage = 1;
      let totalPages = 1;
      let contentResults = [];

      while (currentPage <= totalPages) {
        requestParams.pageNum = currentPage;
        requestParams.pageSize = 10;
        requestParams.contentType = contentType;
        requestParams = {
          ...requestParams,
          ...calculateStartAndEndTime(params),
        };

        try {
          const response = await axios.post(
            "https://pdcreator.pdnews.cn/api/rmrb-bigdata-bi/zh/b/creator/statistic/content/single/list",
            requestParams,
            {
              headers: {
                ...headers,
                Cookie: cookieString,
                "Content-Type": "application/json",
              },
            }
          );

          const jsonData = response.data;
          if (jsonData.data && Array.isArray(jsonData.data.list)) {
            // 筛选符合条件的数据
            const baseUrl =
              "https://www.peopleapp.com/" +
              (contentType === 3 ? "rmhvideo" : "rmharticle");
            const filterData = jsonData.data.list.map((item) => ({
              title: item.contentName,
              id: item.contentId,
              url: baseUrl + "/" + item.contentId,
              publish_time: item.publishTime,
              exposures_count: item.exposures,
              read_count: item.weightViews,
              like_count: item.weightLikes,
              comment_count: item.weightComments,
              share_count: item.shares,
              content_type: contentType === 3 ? "video" : "article",
            }));

            contentResults = contentResults.concat(filterData);
            logger.info(
              `已获取第 ${currentPage} 页 ${
                contentType === 3 ? "视频" : "文章"
              } 数据，当前共 ${contentResults.length} 条`
            );
            totalPages = Math.ceil(jsonData.data.totalCount / 10);
          }

          currentPage++;

          // 添加一些延迟以避免请求过于频繁
          await new Promise((resolve) => setTimeout(resolve, 2000));
        } catch (error) {
          logger.error(
            `获取第 ${currentPage} 页 ${
              contentType === 3 ? "视频" : "文章"
            } 数据时出错: ${error.message}`
          );
          if (error.response) {
            logger.error(
              `Error response: ${JSON.stringify(error.response.data)}`
            );
            logger.error(`Error status: ${error.response.status}`);
            logger.error(
              `Error headers: ${JSON.stringify(error.response.headers)}`
            );
          }
          break;
        }
      }

      return contentResults;
    }

    // 获取文章数据（默认 contentType）
    const articles = await getContent(1);

    // 获取视频数据（contentType = 3）
    const videos = await getContent(3);

    // 合并结果
    results = [...articles, ...videos];

    logger.info(
      `总共获取到 ${results.length} 条数据（文章：${articles.length}，视频：${videos.length}）`
    );
    return results;
  } catch (error) {
    logger.error(`抓取作品信息失败: ${error.message}`);
    throw error;
  } finally {
    if (browser) {
      await browser.close();
    }
  }
}

//
// 登录逻辑, 通过监控用户扫码登录
async function login(page) {
  const maxWaitTime = 10 * 60 * 1000; // 10分钟
  const checkInterval = 5000; // 每5秒检查一次
  const startTime = Date.now();

  logger.info("未登录，开始登录流程...");

  await notification(
    "人民号",
    `${process.env.NODE_ENV}环境下的人民号未登录`,
    "未登录"
  );
  // 初始获取并发送二维码
  await getAndSendQRCode(page);

  while (Date.now() - startTime < maxWaitTime) {
    try {
      // 等待登录成功或二维码更新
      const loginResult = await Promise.race([
        page.waitForNavigation({ timeout: checkInterval }),
        page.waitForResponse(
          (response) =>
            response
              .url()
              .includes(
                "https://pdcreator.pdnews.cn/api/rmrb-user-center/app/qr/authorize"
              ),
          { timeout: checkInterval }
        ),
      ]);

      if (loginResult && loginResult.url) {
        if (
          loginResult
            .url()
            .includes(
              "https://pdcreator.pdnews.cn/producer/analysis/content/single"
            )
        ) {
          logger.info("登录成功");
          await notification(
            "人民号",
            `${process.env.NODE_ENV}环境下的人民号`,
            "登录成功"
          );
          return;
        } else if (
          loginResult
            .url()
            .includes(
              "https://pdcreator.pdnews.cn/api/rmrb-user-center/app/qr/authorize"
            )
        ) {
          // 二维码过期，重新获取并发送
          logger.info("二维码已过期，重新获取并发送");
          await notification(
            "人民号",
            `${process.env.NODE_ENV}环境下的人民号二维码已过期`,
            "正在刷新二维码"
          );
          await getAndSendQRCode(page);
        }
      }
    } catch (error) {
      if (error.name !== "TimeoutError") {
        logger.error(`登录过程中发生错误: ${error.message}`);
        throw error;
      }
    }
  }

  logger.error("登录超时");
  await notification(
    "人民号",
    `${process.env.NODE_ENV}环境下的人民号登录失败`,
    "登录超时"
  );
  throw new Error("登录超时");
}

// 获取并发送二维码的函数
async function getAndSendQRCode(page) {
  logger.info("开始获取人民号登录二维码");
  await page.waitForSelector(".qrcodeWrap canvas", { timeout: 10000 });

  const qrCodeDataUrl = await page.evaluate(() => {
    const canvas = document.querySelector(".qrcodeWrap canvas");
    return canvas.toDataURL();
  });

  const bufferImage = Buffer.from(qrCodeDataUrl.split(",")[1], "base64");

  await sendQRCodeToWechat(bufferImage);
  logger.info("人民号登录二维码获取成功");
  logger.info("二维码已发送到企业微信机器人");
}

// 发送二维码到企业微信机器人
async function sendQRCodeToWechat(bufferImage) {
  logger.info(`人民号登录二维码获取成功`);
  const imgBase64 = bufferImage.toString("base64");
  try {
    await sendWechatMessage({
      msgtype: "image",
      image: {
        base64: imgBase64,
        md5: md5(bufferImage),
      },
    });
    logger.info(`发送图片信息成功`);
    return true;
  } catch (error) {
    logger.error(`发送图片信息失败:${error.message}`);
  }
}
// 计算开始时间和结束时间
function calculateStartAndEndTime(params) {
  const now = dayjs();
  // 如果 highFrequency 计算最近七天, 否则计算最近三十天
  if (params.update_type === "highFrequency") {
    return {
      startDate: now.subtract(7, "day").format("YYYY-MM-DD"),
      endDate: now.format("YYYY-MM-DD"),
    };
  } else {
    // 2024-01-01 开始
    return {
      startDate: "2024-01-01",
      endDate: now.format("YYYY-MM-DD"),
    };
  }
}

exports.handleCommand = async (command, params) => {
  switch (command) {
    case "getArticlesInfo":
      const data = await getArticlesInfo(params);
      return { data };
    // 其他命令...
    default:
      throw new Error("Unsupported command");
  }
};
